﻿/******************************************************************************
 * Copyright (C) 671643387@qq.com
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 *****************************************************************************/

#include "AuthSessionManager.h"
#include <NodeCpp/AutoPtr.h>
#include <NodeCpp/Thread.h>
#include "GlobalVars.h"
#include "AuthSession.h"
using NodeCpp::AutoPtr;
using NodeCpp::Thread;

AuthSessionManager::AuthSessionManager(void)
    : NewSessions_()
    , Sessions_()
    , Running_(true)
    , MaxUnauthedTime_(5)
{

}

AuthSessionManager::~AuthSessionManager(void)
{

}

AuthSession* AuthSessionManager::NewSession(WorldSocketDelegate* _Sock)
{
    AuthSession* _Session = new AuthSession(_Sock);
    if (_Session) {
        NewSessions_.Add(_Session);
        return _Session;
    }
    return NULL;
}

void AuthSessionManager::Update(time_t _Diff)
{
    // 将新会话加入队列
    AuthSession* _AddSession;
    while (NewSessions_.Next(_AddSession)) {
        Sessions_[_AddSession->GetID()] = _AddSession;
    }

    // 更新会话
    SessionMap::iterator _Iter = Sessions_.begin();
    for (; _Iter != Sessions_.end();) {
        AutoPtr<AuthSession> _Session(_Iter->second);
        if (!_Session->Update(_Diff)) {
            _Iter = Sessions_.erase(_Iter);
            continue;
        }
        _Session.release();

        ++_Iter;
    }
}

void AuthSessionManager::Close(void)
{
    const time_t WaitTime = 20;
    Running_ = false;
    while (!(Sessions_.empty() && NewSessions_.Empty())) {
        Update(WaitTime);
        Thread::Sleep(WaitTime);
    }
}

AuthSession* AuthSessionManager::FindSession(int _ID)
{
    return Sessions_[_ID];
}